
# -*- coding:utf-8 -*-

import os,copy
#创建queue_client.py
def replace_queue_client___first_name(queue_name):
    global queue_client
    #___first_name        第一个queue_name
    queue_client=queue_client.replace('___first_name',queue_name)
def replace_queue_client(queue_name_lst):
    global queue_client
    #queue_name_lst列表
    str1=''
    str2=''
    str1_1='___connect_queue'
    str2_1='___set_dct'
    for item in queue_name_lst:
        str1=str1+'        self.connect_queue_%s=connect_queue_%s()'%(item,item)+'\n'
        str2=str2+"        self.dct['%s']=self.connect_queue_%s"%(item,item)+'\n'
    queue_client=queue_client.replace(str1_1,str1)
    queue_client=queue_client.replace(str2_1,str2)
queue_client=r"""# -*- coding:utf-8 -*-

#需要先运行的函数
import os,sys
project_dir_path=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  #项目路径
sys.path.append(project_dir_path)           #将项目路径添加到环境中   使得python可以导包
from queue_dir.client_queue import *        #导包
class queue_client_class:
    def __init__(self):
___connect_queue
        self.dct={}
___set_dct
    def put(self,name='___first_name'):
        for i in range(5):
            val={'3':444}
            self.dct[name].put(val)
            print('put ',name,val)
    def run(self,name='___first_name'):#get
        while 1:
            while 1:
                if self.dct[name].qsize() > 0:
                    val=self.dct[name].get()
                    print('get ',name,val)
                else:
                    break
            time.sleep(0.1)
if __name__=='__main__':
    queue_main=queue_client_class()
    queue_main.put('___first_name')
    # queue_main.run('___first_name')
"""
#创建queue_main.py
def replace_queue_main(queue_name_lst):
    global queue_main
    #queue_name_lst列表
    str1=''
    str2=''
    str3=''
    str4=''
    str1_1='___dao_bao'#导包
    str2_1='___start_que'#启动queue
    str3_1='___run_get'#避免包越堆越多
    str4_1='___test_get'#测试
    for item in queue_name_lst:
        str1=str1+'from queue_dir.queue_%s import *   #导包'%(item)+'\n'
        str2=str2+"        self.queue_%s=queue_%s().start()"%(item,item)+'\n'
        str3=str3+r"""            if self.queue_%s.qsize() > 500:
                val=self.queue_%s.get()
                with open(self.queue_main_log_path, 'a') as f:
                    print(now_time,'%s',' 抛出数据\n',val, file=f)"""%(item,item,item)+'\n'
        str4=str4+r"""            while 1:
                if self.queue_%s.qsize() > 0:
                    val=self.queue_%s.get()
                    print('get %s',val)
                else:
                    break"""%(item,item,item)+'\n'
    queue_main=queue_main.replace(str1_1,str1)
    queue_main=queue_main.replace(str2_1,str2)
    queue_main=queue_main.replace(str3_1,str3)
    queue_main=queue_main.replace(str4_1,str4)
queue_main=r"""# -*- coding:utf-8 -*-

#需要先运行的函数
import os,sys,time,datetime
project_dir_path=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  #项目路径
sys.path.append(project_dir_path)           #将项目路径添加到环境中   使得python可以导包
___dao_bao
def now_time():
    return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
class queue_main_class:
    def __init__(self):
        self.queue_main_log_path=project_dir_path+os.sep+'queue_main_log.txt'
___start_que
    def run(self):
        while 1:
___run_get
            time.sleep(5)
    def test(self):
        while 1:
___test_get
            time.sleep(0.1)
if __name__=='__main__':
    queue_main=queue_main_class()
    #queue_main.run()
    queue_main.test()
"""

#创建client_queue.py
def replace_client_queue(queue_lst):
    global client_queue
    #queue_name_lst列表
    str1=''
    str1_1='___def'#导包
    for item in queue_lst:
        #{'queue_name':'db_send_web','host':host,'port':'9991','authkey':b'erfsad'},
        str1=str1+f"""def connect_queue_{item['queue_name']}(**kwargs):
    while True:
        try:
            QueueManager.register('{item['queue_name']}')
            manager = QueueManager(address=('{item['host']}',{item['port']}), authkey=b'{item['authkey']}')
            manager.connect()
            return manager.{item['queue_name']}()
            break
        except Exception as e:
            if kwargs.get('self') is not None:
                kwargs['self'].log.printerror('队列db_send_web无法连接:',str(traceback.format_exc()))
            time.sleep(1)"""+'\n'
    client_queue=client_queue.replace(str1_1,str1)

client_queue="""# -*- coding:utf-8 -*-

import traceback,time
from multiprocessing.managers import BaseManager
class QueueManager(BaseManager):
    pass
___def"""
#创建queue_xxxxx.py
def create_queue_xxxxx(queue_lst):
    res_str_dct={}
    #queue_name_lst列表
    for item in queue_lst:
        res_str_dct['queue_'+item['queue_name']+'.py']=f"""# -*- coding:utf-8 -*-
# 服务进程在windows系统和Linux系统上有所不同
# 创建一个分布式进程:包括服务进程和任务进程
# 多个进程之间的通信使用Queue
# 该代码为服务进程
# 注意，运行时先运行服务进程，再运行任务进程
# 任务执行循序:
# 服务进程和任务进行都创建了相同的两个队列，一个用来放任务，一个用来放结果
# 第一步:服务进程运行，比如将数字2放进任务队列，任务进程从任务队列中取出数字2
# 第二步:取出数字，执行任务，就是2*2=4, 任务执行完后，放进结果队列
# 第三步:服务进程从结果队列中，取出结果。
# 第四步:所有任务执行完毕，所有结果都已经取出，最终任务队列和结果队列都是空的了
import queue
from multiprocessing.managers import BaseManager
class QueueManager(BaseManager):
    pass
        
{item['queue_name']} = queue.Queue() 
class queue_{item['queue_name']}:
    def return_{item['queue_name']}(self):
        global {item['queue_name']} # 定义成全局变量
        return {item['queue_name']} # 返回发送任务的队列
    def __init__(self,is_client=True):
        # 第二步:把上面创建的两个队列注册在网络上，利用register方法
        # callable参数关联了Queue对象，将Queue对象在网络中暴露
        # 第一个参数是注册在网络上队列的名称
        QueueManager.register('{item['queue_name']}', callable=self.return_{item['queue_name']})
        # 第三步:绑定端口8001，设置验证口令,这个相当于对象的初始化
        # 绑定端口并填写验证口令，windows下需要填写IP地址，Linux下默认为本地，地址为空
        self.manager = QueueManager(address=('{item['host']}',{item['port']}), authkey=b'{item['authkey']}') # 口令必须写成类似b'dihuge'形式，只写'dihuge'运行错误
    def start(self):
        self.manager.start()
        self.task = self.manager.{item['queue_name']}()
        return self.task
"""
    return res_str_dct

#创建分布式队列文件的
class queue_class:
    def __init__(self,queue_lst,dir_path):
        #删除文件夹 然后重新创建文件夹
        try:os.remove(dir_path)
        except:pass
        try:os.removedirs(dir_path)
        except:pass
        try:os.mkdirs(dir_path)
        except:pass
        #__init__.py内容
        self.init_info=[]
        #创建queue_xxxxx.py
        res=create_queue_xxxxx(queue_lst)
        for key in res:
            with open(dir_path+os.sep+key,'w',encoding='utf-8')as f:
                f.write(res[key])
            self.init_info.append(key[:-3])
        #创建client_queue.py
        replace_client_queue(queue_lst)
        with open(dir_path+os.sep+"client_queue.py",'w',encoding='utf-8')as f:
            f.write(client_queue)
        self.init_info.append('client_queue.py')
        #创建queue_client.py
        first_queue_name=queue_lst[0]['queue_name']
        queue_name_lst=[item['queue_name']for item in queue_lst]
        replace_queue_client___first_name(first_queue_name)
        replace_queue_client(queue_name_lst)
        with open(dir_path+os.sep+"queue_client.py",'w',encoding='utf-8')as f:
            f.write(queue_client)
        #创建queue_main.py
        replace_queue_main(queue_name_lst)
        with open(dir_path+os.sep+"queue_main.py",'w',encoding='utf-8')as f:
            f.write(queue_main)
        #创建__init__.py
        with open(dir_path+os.sep+"__init__.py",'w',encoding='utf-8')as f:
            f.write("__all__="+str(self.init_info))
if __name__=="__main__":
    ######################相关说明###########################
    #会在dir_path路径下面创建多个py文件
    #其中   queue_main.py为server演示文件  必须优先启动
    #其中   queue_client.py 为client演示文件 可以连接server创建的通道 从而发数据 或者收数据
    ######################参数设置###########################
    host='127.0.0.1'
    dir_path=os.path.abspath(os.path.dirname(os.path.abspath(__file__)))+os.sep+r'queue_dir'#创建que文件的文件夹路径
    queue_lst=[
            {'queue_name':'db_send_web','host':host,'port':'9991','authkey':'erfsad'},
            {'queue_name':'web_send_db','host':host,'port':'9992','authkey':'fsdsa'},
        ]
    ######################运行##############################
    try:os.makedirs(dir_path)#没有就创建文件夹
    except:pass
    queue_class(queue_lst,dir_path=dir_path)